import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
//lass JoyCacheManager extends StatefulWidget{

class JoyCacheManager {
  static const key = 'joy_cache';

  static CacheManager _instance = CacheManager(
    Config(
      key,
      stalePeriod: const Duration(days: 7), // Expires in 7 days
      maxNrOfCacheObjects: 500, // Maximum number of cached files
      repo: JsonCacheInfoRepository(databaseName: key),
      fileService: HttpFileService(),
      fileSystem: IOFileSystem(key),
    ),
  );

  static CacheManager get instance => _instance;

  // Set maximum cache to 300MB
  static Future<void> initCacheManager() async {
    try {
      final cacheDir = await getTemporaryDirectory();
      final customCacheDir = Directory(path.join(cacheDir.path, 'joy_image_cache'));

      _instance = CacheManager(
        Config(
          key,
          stalePeriod: const Duration(days: 15), // Expires in 15 days
          maxNrOfCacheObjects: 1000, // Maximum number of cached files
          repo: JsonCacheInfoRepository(databaseName: key),
          fileService: HttpFileService(),
          fileSystem: IOFileSystem(customCacheDir.path),
        ),
      );

      // Periodically check and limit cache size to 300MB
      await _checkAndLimitCacheSize();
    } catch (e) {
      print('Failed to initialize cache manager: $e');
    }
  }

  // Check and limit cache size
  static Future<void> _checkAndLimitCacheSize() async {
    try {
      const maxCacheSize = 300 * 1024 * 1024; // 300MB
      final cacheSize = await _getCacheSize();

      if (cacheSize > maxCacheSize) {
        // If it exceeds 300MB, clear some cache
        await _cleanOldCache();
      }
    } catch (e) {
      print('Failed to check cache size: $e');
    }
  }

  // Get current cache size
  static Future<int> _getCacheSize() async {
    try {
      // Get cache directory from flutter_cache_manager
      final cacheDir = await getTemporaryDirectory();
      print('Temp directory: ${cacheDir.path}');

      final customCacheDir = Directory(path.join(cacheDir.path, 'joy_image_cache'));

      int totalSize = 0;
      int customSize = 0;
      int defaultSize = 0;
      int ourSize = 0;

      // Check custom cache directory
      if (customCacheDir.existsSync()) {
        print('Custom cache dir exists: ${customCacheDir.path}');
        await for (final entity in customCacheDir.list(recursive: true)) {
          if (entity is File) {
            final fileSize = await entity.length();
            customSize += fileSize;
            totalSize += fileSize;
          }
        }
        print('Custom cache size: $customSize bytes');
      } else {
        print('Custom cache dir does not exist: ${customCacheDir.path}');
      }

      // Also check flutter_cache_manager default cache
      try {
        final defaultCacheDir = Directory(path.join(cacheDir.path, 'libCachedImageData'));
        if (defaultCacheDir.existsSync()) {
          print('Default cache dir exists: ${defaultCacheDir.path}');
          await for (final entity in defaultCacheDir.list(recursive: true)) {
            if (entity is File) {
              final fileSize = await entity.length();
              defaultSize += fileSize;
              totalSize += fileSize;
            }
          }
          print('Default cache size: $defaultSize bytes');
        } else {
          print('Default cache dir does not exist: ${defaultCacheDir.path}');
        }
      } catch (e) {
        print('Error reading default cache: $e');
      }

      // Check our specific cache manager files
      try {
        final ourCacheDir = Directory(path.join(cacheDir.path, key));
        if (ourCacheDir.existsSync()) {
          print('Our cache dir exists: ${ourCacheDir.path}');
          await for (final entity in ourCacheDir.list(recursive: true)) {
            if (entity is File) {
              final fileSize = await entity.length();
              ourSize += fileSize;
              totalSize += fileSize;
            }
          }
          print('Our cache size: $ourSize bytes');
        } else {
          print('Our cache dir does not exist: ${ourCacheDir.path}');
        }
      } catch (e) {
        print('Error reading our cache: $e');
      }

      print('Total cache size: $totalSize bytes');
      return totalSize;
    } catch (e) {
      print('Failed to get cache size: $e');
      return 0;
    }
  }

  // Clear old cache
  static Future<void> _cleanOldCache() async {
    try {
      // Clear expired files
      await _instance.emptyCache();

      // Recheck cache size
      final cacheSize = await _getCacheSize();
      const maxCacheSize = 300 * 1024 * 1024; // 300MB

      if (cacheSize > maxCacheSize) {
        // If it still exceeds, delete the oldest files
        final cacheDir = await getTemporaryDirectory();
        final customCacheDir = Directory(path.join(cacheDir.path, 'joy_image_cache'));

        final files = <FileSystemEntity>[];
        await for (final entity in customCacheDir.list(recursive: true)) {
          if (entity is File) {
            files.add(entity);
          }
        }

        // Sort by modification time, delete the oldest files
        files.sort((a, b) {
          final aStat = a.statSync();
          final bStat = b.statSync();
          return aStat.modified.compareTo(bStat.modified);
        });

        int currentSize = cacheSize;
        for (final file in files) {
          if (currentSize <= maxCacheSize * 0.8) break; // Delete to 80% of size

          try {
            final fileSize = await (file as File).length();
            await file.delete();
            currentSize -= fileSize;
          } catch (e) {
            print('Failed to delete cache file: $e');
          }
        }
      }
    } catch (e) {
      print('Failed to clear cache: $e');
    }
  }

  // Clear all cache
  static Future<void> clearAllCache() async {
    try {
      await _instance.emptyCache();
    } catch (e) {
      print('Failed to clear cache: $e');
    }
  }

  // Get cache information
  static Future<Map<String, dynamic>> getCacheInfo() async {
    try {
      print('Getting cache info...');
      final cacheSize = await _getCacheSize();
      final fileCount = await _getCacheFileCount();

      print('Cache size: $cacheSize bytes, File count: $fileCount');

      final sizeInMB = (cacheSize / (1024 * 1024)).toStringAsFixed(2);

      return {
        'size': cacheSize,
        'fileCount': fileCount,
        'sizeInMB': sizeInMB,
      };
    } catch (e) {
      print('Failed to get cache information: $e');
      return {
        'size': 0,
        'fileCount': 0,
        'sizeInMB': '0.00',
      };
    }
  }

  // Get cache file count
  static Future<int> _getCacheFileCount() async {
    try {
      final cacheDir = await getTemporaryDirectory();
      final customCacheDir = Directory(path.join(cacheDir.path, 'joy_image_cache'));

      int fileCount = 0;

      // Check custom cache directory
      if (customCacheDir.existsSync()) {
        await for (final entity in customCacheDir.list(recursive: true)) {
          if (entity is File) {
            fileCount++;
          }
        }
      }

      // Also check flutter_cache_manager default cache
      try {
        final defaultCacheDir = Directory(path.join(cacheDir.path, 'libCachedImageData'));
        if (defaultCacheDir.existsSync()) {
          await for (final entity in defaultCacheDir.list(recursive: true)) {
            if (entity is File) {
              fileCount++;
            }
          }
        }
      } catch (e) {
        print('Error reading default cache: $e');
      }

      // Check our specific cache manager files
      try {
        final ourCacheDir = Directory(path.join(cacheDir.path, key));
        if (ourCacheDir.existsSync()) {
          await for (final entity in ourCacheDir.list(recursive: true)) {
            if (entity is File) {
              fileCount++;
            }
          }
        }
      } catch (e) {
        print('Error reading our cache: $e');
      }

      return fileCount;
    } catch (e) {
      print('Failed to get cache file count: $e');
      return 0;
    }
  }
}


